; 初始化：控制变量i=100 → 存入地址100（避免占用目标内存0~99）
PUSH 100
STORE 100

LOOP:          ; 循环入口
; 1. 更新i：i = i - 1
LOAD 100       ; 栈：[当前i]
PUSH 1         ; 栈：[当前i, 1]
SUB            ; 栈：[i-1]
STORE 100      ; 更新地址100的i

; 2. 操作内存：MEM[i] = i
LOAD 100       ; 栈：[当前i]（待写入的值）
LOAD 100       ; 栈：[当前i, 当前i]（待写入的地址）
STORE_INDIRECT ; 执行MEM[地址] = 值

; 3. 终止判断：i==0？若是则跳至PRIME_LEFT
LOAD 100       ; 栈：[当前i]
PUSH 0         ; 栈：[当前i, 0]
EQ             ; 栈：[1若i==0，否则0]
JUMPIF PRIME_LEFT    ; 当i=0时进入素数筛选

JUMP LOOP      ; 否则跳回LOOP入口

PRIME_LEFT:          ; 子程序：筛法，将素数留下来
    ; 初始化p=2（素数筛选的起始值），存储在地址1
    PUSH 2
    STORE 1           ; m[1] = p = 2

P_LOOP:               ; p的外层循环入口（p从2到99）
    ; 优化：检查p*p是否小于等于100，若大于则结束筛选
    LOAD 1            ; 栈：[p]
    LOAD 1            ; 栈：[p, p]
    MUL               ; 栈：[p*p]
    PUSH 100          ; 栈：[p*p, 100]
    GT                ; 栈：[1若p*p>100，否则0]
    JUMPIF HALT       ; 若p*p>100则结束程序，无需继续筛选
    
    ; 检查MEM[p]是否为0（用EQ实现：若等于0则不是素数）
    LOAD 1            ; 栈：[p]（地址）
    LOAD_INDIRECT     ; 栈：[MEM[p]]（获取p地址的值）
    PUSH 0            ; 栈：[MEM[p], 0]
    EQ                ; 栈：[1若MEM[p]==0，否则0]
    JUMPIF SKIP_MARK  ; 若MEM[p]==0（非素数），则跳过标记
    ; 能执行到这里，说明MEM[p]≠0（是素数），执行标记倍数
    JUMP MARK_MULTIPLES

MARK_MULTIPLES:       ; 标记p的所有倍数为非素数
    ; 计算内循环初始值i = p*p，存储在地址0
    LOAD 1            ; 栈：[p]
    LOAD 1            ; 栈：[p, p]
    MUL               ; 栈：[p*p]
    STORE 0           ; m[0] = i = p*p

I_LOOP:               ; i的内层循环入口（标记倍数）
    ; 检查i是否小于100，若不小于则结束内循环
    LOAD 0            ; 栈：[i]
    PUSH 100          ; 栈：[i, 100]
    LT                ; 栈：[1若i<100，否则0]
    JUMPIF I_CONTINUE ; i<100则继续标记
    JUMP SKIP_MARK    ; i>=100则结束内循环

I_CONTINUE:           ; 标记当前i为非素数
    ; 将MEM[i]设为0（标记为非素数）
    PUSH 0            ; 栈：[0]（要存入的值）
    LOAD 0            ; 栈：[0, i]（目标地址）
    STORE_INDIRECT    ; 执行MEM[i] = 0

    ; 更新i = i + p（下一个倍数）
    LOAD 0            ; 栈：[i]
    LOAD 1            ; 栈：[i, p]
    ADD               ; 栈：[i+p]
    STORE 0           ; 更新i的值
    JUMP I_LOOP       ; 回到内循环入口

SKIP_MARK:            ; 跳过标记（或内循环结束后），更新p
    ; p = p + 1（下一个待判断的数）
    LOAD 1            ; 栈：[p]
    PUSH 1            ; 栈：[p, 1]
    ADD               ; 栈：[p+1]
    STORE 1           ; 更新p的值
    JUMP P_LOOP       ; 回到外循环入口

HALT:                 ; 程序结束
HALT